home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / CPTUTT22.ZIP / CHAP07.TXT < prev    next >
Text File  |  1992-01-20  |  22KB  |  472 lines

  1.  
  2.  
  3.  
  4.  
  5.  
  6.  
  7.                                                         Chapter 7
  8.                                                       INHERITANCE
  9.  
  10. One reason to use inheritance is that it allows you to reuse code
  11. from a previous project but gives you the flexibility to slightly
  12. modify it if the old code doesn't do exactly what you need for the
  13. new project.  It doesn't make sense to start every new project from
  14. scratch since some code will certainly be repeated in several
  15. programs and you should strive to build on what you did previously.
  16. Moreover, it is easy to make an error if we try to modify the
  17. original class, but we are less likely to make an error if we leave
  18. the original alone and only add to it.  Another reason for using
  19. inheritance is if the project requires the use of several classes
  20. which are very similar but slightly different.
  21.  
  22. In this chapter we will concentrate on the mechanism of inheritance
  23. and how to build it into a program.  A better illustration of why
  24. you would use inheritance will be given in later chapters where we
  25. will discuss some practical applications of object oriented
  26. programming.
  27.  
  28. The principle of inheritance is available with several modern
  29. programming languages and is handled slightly differently with
  30. each.  C++ allows you to inherit all or part of the members and
  31. methods of a class, modify some, and add new ones not available in
  32. the parent class.  You have complete flexibility, and as usual,
  33. the method used with C++ has been selected to result in the most
  34. efficient code execution.
  35.  
  36.  
  37. A SIMPLE CLASS TO START WITH
  38. _________________________________________________________________
  39.  
  40. Examine the file named VEHICLE.H for a simple   =================
  41. class which we will use to begin our study of       VEHICLE.H
  42. inheritance in this chapter.  There is nothing  =================
  43. unusual about this class header, it has been
  44. kept very simple.  It consists of four simple
  45. methods which can be used to manipulate data pertaining to our
  46. vehicle.  What each method does is not especially important at this
  47. time.  We will eventually refer to this as a base class or parent
  48. class, but for the time being, we will simply use it like any other
  49. class to show that it is indeed identical to the classes already
  50. studied.  Note that we will explain the added keyword protected
  51. shortly.
  52.  
  53. Ignore lines 4, 5, and 17 until the end of this chapter where they
  54. will be explained in detail.  This file cannot be compiled or
  55. executed because it is only a header file.
  56.  
  57.  
  58.                                                          Page 7-1
  59.  
  60.                                           Chapter 7 - Inheritance
  61.  
  62.  
  63. THE IMPLEMENTATION FOR VEHICLE
  64. _________________________________________________________________
  65.  
  66. Examine the file named VEHICLE.CPP and you will   ===============
  67. find that it is the implementation of the           VEHICLE.CPP
  68. vehicle class.  The initialize() method assigns   ===============
  69. the values input as parameters to the wheels and
  70. weight variables.  We have methods to return the
  71. number of wheels and the weight, and finally, we have one that does
  72. a trivial calculation to return the loading on each wheel.  We will
  73. have a few examples of methods that do some significant processing
  74. later, but at this point, we are more interested in learning how
  75. to set up the interface to the classes, so the implementations will
  76. be kept trivial.
  77.  
  78. As stated above, this is a very simple class which will be used in
  79. the next program.  Later in this tutorial we will use it as a base
  80. class.  You should compile this class at this time in preparation
  81. for the next example program, but you cannot execute it because
  82. there is no entry point.
  83.  
  84.  
  85. USING THE VEHICLE CLASS
  86. _________________________________________________________________
  87.  
  88. The file named TRANSPRT.CPP uses the vehicle     ================
  89. class in exactly the same manner as we             TRANSPRT.CPP
  90. illustrated in the last chapter.  This should be ================
  91. an indication to you that the vehicle class is
  92. truly nothing more than a normal class as
  93. defined in C++.  We will make it a little special, however, by
  94. using it unmodified as a base class in the next few example files
  95. to illustrate inheritance.  Inheritance uses an existing class and
  96. adds functionality to it to accomplish another, possibly more
  97. complex job.
  98.  
  99. You should have no problem understanding the operation of this
  100. program.  It declares four objects of the vehicle class,
  101. initializes them, and prints out a few of the data points to
  102. illustrate that the vehicle class can be used as a simple class
  103. because it is a simple class.  We are referring to it as a simple
  104. class as opposed to calling it a base class or derived class as we
  105. will do shortly.
  106.  
  107. If you thoroughly understand this program, you should compile and
  108. execute it, remembering to link the vehicle object file with this
  109. object file.
  110.  
  111. OUR FIRST DERIVED CLASS
  112. _________________________________________________________________
  113.  
  114. Examine the file named CAR.H for our first example of the use of
  115. a derived class or child class.  The vehicle class is inherited due
  116.  
  117.                                                          Page 7-2
  118.  
  119.                                           Chapter 7 - Inheritance
  120.  
  121. to the ": public vehicle" added to line 4.  This   ==============
  122. derived class named car is composed of all of           CAR.H
  123. the information included in the base class         ==============
  124. vehicle, and all of its own additional
  125. information.  Even though we did nothing to the
  126. class named vehicle, we made it into a base class because of the
  127. way we are using it here.  To go a step further, even though it
  128. will be used as a base class in an example program later in this
  129. chapter, there is no reason it cannot continue to be used as a
  130. simple class in the previous example program.  In fact, it can be
  131. used as a single class and a base class in the same program.  The
  132. question of whether it is a simple class or a base class is
  133. answered by the way it is used.
  134.  
  135. A discussion of terminology is needed here.  When discussing object
  136. oriented programming in general, a class that inherits another is
  137. often called a derived class or a child class, but the most proper
  138. term as defined for C++ is a derived class.  Since these terms are
  139. very descriptive, and most writers tend to use the terms
  140. interchangeably, we will also use these terms in this tutorial.
  141. Likewise the proper C++ terminology for the inherited class is to
  142. call it a base class, but parent class and super class are
  143. sometimes used.
  144.  
  145. A base class is a rather general class which can cover a wide range
  146. of objects, whereas a derived class is somewhat more restricted but
  147. at the same time more useful.  For example if we had a base class
  148. named programming language and a derived class named C++, then we
  149. could use the base class to define Pascal, Ada, C++, or any other
  150. programming language, but it would not tell us about the use of
  151. classes in C++ because it can only give a general view of each
  152. language.  On the other hand, the derived class named C++ could
  153. define the use of classes, but it could not be used to describe the
  154. other languages because it is too narrow.  A base class tends to
  155. be more general, and a derived class is more specific.
  156.  
  157. In this case, the vehicle base class can be used to declare objects
  158. that represent trucks, cars, bicycles, or any number of other
  159. vehicles you can think up.  The class named car however can only
  160. be used to declare an object that is of type car because we have
  161. limited the kinds of data that can be intelligently used with it.
  162. The car class is therefore more restrictive and specific than the
  163. vehicle class.  The vehicle class is more general than the car
  164. class.
  165.  
  166. If we wished to get even more specific, we could define a derived
  167. class using car as the base class and name it sports_car and
  168. include such information as red_line_limit for the tachometer which
  169. would be silly for the family station wagon.  The car class would
  170. therefore be used as a derived class and a base class at the same
  171. time, so it should be clear that these names refer to how a class
  172. is used.
  173.  
  174.  
  175.  
  176.                                                          Page 7-3
  177.  
  178.                                           Chapter 7 - Inheritance
  179.  
  180. HOW DO WE DECLARE A DERIVED CLASS?
  181. _________________________________________________________________
  182.  
  183. Enough generalities about classes, let's get down to the specifics.
  184. A derived class is defined by including the header file for the
  185. base class as is done in line 2, then the name of the base class
  186. is given following the name of the derived class separated by a
  187. colon as is illustrated in line 4.  Ignore the keyword public
  188. immediately following the colon in this line.  It is optional and
  189. we will study it in detail in the next chapter.  All objects
  190. declared as being of class car therefore are composed of the two
  191. variables from the class vehicle because they inherit those
  192. variables, and the single variable declared in the class car named
  193. passenger_load.
  194.  
  195. An object of this class will have three of the four methods of
  196. vehicle and the two new ones declared here.  The method named
  197. initialize() which is part of the vehicle class will not be
  198. available here because it is hidden by the local version of
  199. initialize() which is a part of the car class.  The local method
  200. will be used if the name is repeated allowing you to customize your
  201. new class.  Figure 7-1 is a graphical representation of an object
  202. of this class.
  203.  
  204. Note once again that the implementation for the base class only
  205. needs to be supplied in its compiled form.  The source code for the
  206. implementation can be hidden for economic reasons to aid software
  207. developers.  Hiding the source code also allows the practice of
  208. information hiding.  The header for the base class must be
  209. available as a text file since the class definitions are required
  210. in order to use the class.
  211.  
  212.  
  213.  
  214. THE CAR CLASS IMPLEMENTATION
  215. _________________________________________________________________
  216.  
  217. Examine the file named CAR.CPP which is the       ===============
  218. implementation file for the car class.  The           CAR.CPP
  219. first thing you should notice is that this file   ===============
  220. has no indication of the fact that it is a
  221. derived class of any other file, that can only
  222. be determined by inspecting the header file for the class.  Since
  223. we can't tell if it is a derived class or not, it is written in
  224. exactly the same way as any other class implementation file.
  225.  
  226. The implementations for the two new methods are written in exactly
  227. the same way as methods are written for any other class.  If you
  228. think you understand this file, you should compile it for later
  229. use.
  230.  
  231.  
  232.  
  233.  
  234.  
  235.                                                          Page 7-4
  236.  
  237.                                           Chapter 7 - Inheritance
  238.  
  239. ANOTHER DERIVED CLASS
  240. _________________________________________________________________
  241.  
  242. Examine the file named TRUCK.H for an example of  ===============
  243. another class that uses the vehicle class and         TRUCK.H
  244. adds to it.  Of course, it adds different things  ===============
  245. to it because it will specialize in those things
  246. that pertain to trucks.  In fact it adds two
  247. more variables and three methods.  Once again, ignore the keyword
  248. public following the colon in line 7 for a few minutes and we will
  249. cover it in detail in the next chapter of this tutorial.  See
  250. figure 7-2.
  251.  
  252. A very important point that must be made is that the car class and
  253. the truck class have absolutely nothing to do with each other, they
  254. only happen to be derived classes of the same base class or parent
  255. class as it is sometimes called.
  256.  
  257. Note that both the car and the truck classes have methods named
  258. passengers() but this causes no problems and is perfectly
  259. acceptable.  If classes are related in some way, and they certainly
  260. are if they are both derived classes of a common base class, you
  261. would expect them to be doing somewhat similar things.  In this
  262. situation there is a good possibility that a method name would be
  263. repeated in both child classes.
  264.  
  265.  
  266. THE TRUCK IMPLEMENTATION
  267. _________________________________________________________________
  268.  
  269. Examine the file named TRUCK.CPP for the        =================
  270. implementation of the truck class.  It has          TRUCK.CPP
  271. nothing unusual included in it.                 =================
  272.  
  273. You should have no problem understanding this
  274. implementation.  Your assignment at this point is to compile it in
  275. preparation for our example program that uses all three of the
  276. classes defined in this chapter.
  277.  
  278.  
  279. USING ALL THREE CLASSES
  280. _________________________________________________________________
  281.  
  282. Examine the example program named ALLVEHIC.CPP   ================
  283. for an example that uses all three of the          ALLVEHIC.CPP
  284. classes we have been discussing in this chapter. ================
  285. It uses the parent class vehicle to declare
  286. objects and also uses the two child classes to
  287. declare objects.  This was done to illustrate that all three
  288. classes can be used in a single program.
  289.  
  290. All three of the header files for the classes are included in lines
  291. 3 through 5 so the program can use the components of the classes.
  292. Notice that the implementations of the three classes are not in
  293.  
  294.                                                          Page 7-5
  295.  
  296.                                           Chapter 7 - Inheritance
  297.  
  298. view here and do not need to be in view.  This allows the code to
  299. be used without access to the source code for the actual
  300. implementation of the class.  However, it should be clear that the
  301. header file definition must be available.
  302.  
  303. In this example program, only one object of each class is declared
  304. and used but as many as desired could be declared and used in order
  305. to accomplish the programming task at hand.  You will notice how
  306. clean and uncluttered the source code is for this program since the
  307. classes were developed, debugged, and stored away previously, and
  308. the interfaces were kept very simple.  There is nothing new here
  309. so you should have no trouble understanding the operation of this
  310. program.
  311.  
  312. Compiling and executing this program will take a bit of effort but
  313. the process is not complicated.  The three classes and the main
  314. program can be compiled in any order desired.  All four must be
  315. compiled prior to linking the four resulting object (or binary)
  316. files together.  Finally, you can execute the complete program.
  317. Be sure you do the required steps to compile and execute this
  318. program because the effective use of C++ will require you to
  319. compile many separate files and link them together.  This is
  320. because of the nature of the C++ language, but it should not be a
  321. burden if a good "make" capability exists with your compiler.  If
  322. you are using the Borland implementation of C++, the "project"
  323. capability will make this a snap.
  324.  
  325.  
  326. WHY THE #ifndef VEHICLE_H ?
  327. _________________________________________________________________
  328.  
  329. We promised to return to the strange looking preprocessor directive
  330. in lines 4, 5 and 17 in the VEHICLE.H file, and this is the time
  331. for it.  When we define the derived class car, we are required to
  332. supply it with the full definition of the interface to the vehicle
  333. class since car is a derived class of vehicle and must know all
  334. about its parent.  We do that by including the vehicle class into
  335. the car class, and the car class can be compiled.  The vehicle
  336. class must also be included in the header file of the truck class
  337. for the same reason.
  338.  
  339. When we get to the main program, we must inform it of the details
  340. of all three classes, so all three header files must be included
  341. as is done in lines 3 through 5 of ALLVEHIC.CPP, but this leads to
  342. a problem.  When the preprocessor gets to the car class, it
  343. includes the vehicle class because it is listed in the car class
  344. header file, but since the vehicle class was already included in
  345. line 3 of ALLVEHIC.CPP, it is included twice and we attempt to
  346. redefine the class vehicle.  Of course it is the same definition,
  347. but the system doesn't care, it simply doesn't allow redefinition
  348. of a class.  We allow the double inclusion of the file and at the
  349. same time prevent the double inclusion of the class by building a
  350. bridge around it using the word VEHICLE_H.  If the word is already
  351. defined, the definition is skipped, but if the word is not defined,
  352.  
  353.                                                          Page 7-6
  354.  
  355.                                           Chapter 7 - Inheritance
  356.  
  357. the definition is included and the word is defined at that time.
  358. The end result is the actual inclusion of the class only once, even
  359. though the file is included more than once.  You should have no
  360. trouble understanding the logic of the includes if you spend a
  361. little time studying this program sequence.
  362.  
  363. Even though ANSI-C allows multiple definitions of entities,
  364. provided the definitions are identical, C++ does not permit this.
  365. The primary reason is because the compiler would have great
  366. difficulty in knowing if it has already made a constructor call for
  367. the redefined entity, if there is one.  A multiple constructor call
  368. for a single object could cause great havoc, so C++ was defined to
  369. prevent any multiple constructor calls by making it illegal to
  370. redefine any entity.  This is not a problem in any practical
  371. program.
  372.  
  373. The name VEHICLE_H was chosen as the word because it is the name
  374. of the file, with the period replaced by the underline.  If the
  375. name of the file is used systematically in all of your class
  376. definitions, you cannot have a name clash because the filename of
  377. every class must be unique.  It would be good for you to get into
  378. the practice of building the optional skip around all of your
  379. classes.  All class definition files in the remainder of this
  380. tutorial will include this skip around to prevent multiple
  381. inclusions and to be an example for you.  You should get into the
  382. practice of adding the skip around to all of your class headers no
  383. matter how trivial they may seem to be.
  384.  
  385.  
  386.  
  387. OUR FIRST PRACTICAL INHERITANCE
  388. _________________________________________________________________
  389.  
  390. Continuing where we started in chapter 5, we      ===============
  391. will inherit the date class into the file named      NEWDATE.H
  392. NEWDATE.H and add a member variable and a new     ===============
  393. method to the class.  Actually, this is not a
  394. good way to add the day_of_year to the date
  395. class since it is available in the structure returned from the
  396. system call in the date class.  However, we are more interested in
  397. illustrating inheritance in a practical example than we are in
  398. developing a perfect class, so we will live with this inefficiency.
  399. You will note that we add one variable and one method to create our
  400. new class.
  401.  
  402. The program named NEWDATE.CPP contains the        ===============
  403. implementation for the added method and should      NEWDATE.CPP
  404. be simple for the student to understand.  This    ===============
  405. class implementation uses the array days[] from
  406. the date class implementation since it was
  407. defined as a global variable there.  The method named
  408. get_time_of_day() involves very simple logic but still adjusts for
  409. leap years.
  410.  
  411.  
  412.                                                          Page 7-7
  413.  
  414.                                           Chapter 7 - Inheritance
  415.  
  416. Finally, the example program named TRYNDATE.CPP  ================
  417. will use the new class in a very simple way to     TRYNDATE.CPP
  418. illustrate that the derived class is as easy to  ================
  419. use as the base class and in fact the main
  420. program has no way of knowing that it is using
  421. a derived class.
  422.  
  423. You should compile and link this program to gain the experience of
  424. doing so.  Remember that it will be necessary to link in the object
  425. code for the original date class as well as the object code from
  426. the newdate class and the main program.
  427.  
  428.  
  429. PROGRAMMING EXERCISES
  430. _________________________________________________________________
  431.  
  432.  
  433. 1.   Add another object of the vehicle class to ALLVEHIC.CPP named
  434.      bicycle, and do some of the same operations as were done to
  435.      the unicycle.  You will only need to recompile the main
  436.      program and link all four files together to get an executable
  437.      file, the three classes will not require recompilation.
  438.  
  439. 2.   Add the optional skip around the header files of the classes
  440.      named car and truck.  Then recompile all four files and relink
  441.      them to get an executable file.
  442.  
  443. 3.   Add a new method to the truck class to return the total weight
  444.      of the truck plus its payload and add code to ALLVEHIC.CPP to
  445.      read the value out and display it on the monitor.  This will
  446.      require an addition to TRUCK.H, another addition to TRUCK.CPP,
  447.      and of course the changes to the main program named
  448.      ALLVEHIC.CPP.  The answer is given as three files named
  449.      CH07_3A.H (TRUCK.H), CH07_3B.CPP (TRUCK.CPP) and the changed
  450.      main program is found in CH07_3C.CPP in the answer directory
  451.      on the distribution disk for this tutorial.
  452.  
  453. 4.   Add a variable named sex of type char to the name class you
  454.      developed in chapter 5 as well as methods to set and retrieve
  455.      the value of this variable.  The only legal inputs are 'M' or
  456.      'F'.  These additions should be done by inheriting the name
  457.      class into the new class.
  458.  
  459.  
  460.  
  461.  
  462.  
  463.  
  464.  
  465.  
  466.  
  467.  
  468.  
  469.  
  470.  
  471.                                                          Page 7-8
  472.